#include<iostream>
#include<string>
#include<vector>
#include<boost/filesystem.hpp>
#include"tool.hpp"
//是一个目录，下面放的是所有的html网页
const std::string src_path="data/input/";
const std::string output="data/raw_html/raw.txt";
typedef struct DocInfo{
	std::string title;//文档的标题
	std::string content;//文档内容
	std::string url;//该文档在官网中的URL
}DocInfo_t ;
bool EnumFile(const std::string &src_path,std::vector<std::string>*file_list)
{
	namespace fs=boost::filesystem;
	fs::path root_path(src_path);
	//判断路径是否存在，不存在，就没必要往后走了
	if(!fs::exists(root_path))
	{
		std::cerr<<src_path<<"not exists"<<std::endl;
		return false;
	}
	//定义一个空的迭代器，用来进行判断递归结束
	fs::recursive_directory_iterator end;
	for(fs::recursive_directory_iterator iter(root_path);iter!=end;iter++){
		//判断文件是否是普通文件，html都是普通文件
		if(!fs::is_regular_file(*iter))
		{
			continue;
		}
		//判断文件后缀名是否符合要求
		if(iter->path().extension()!=".html")
		{
			continue;
		}
		//当前的路径一定是一个合法的，以html结束的普通网页文件
		file_list->push_back(iter->path().string());
	}
	return true;
}
bool ParseTitle(const std::string &file,std::string*title)
{
	std::size_t begin=file.find("<title>");
	if(begin == std::string::npos){
        return false;
    }
	std::size_t end=file.find("<title>");
	if(end == std::string::npos){
        return false;
    }
	begin += std::string("<title>").size();
	*title=file.substr(begin,end-begin);
	return true;

}
bool ParseContent(const std::string &file, std::string *content)
{
	enum status{
		LABLE,
		CONTENT
	};
	status s=LABLE;
	for(char c:file)
	{
		switch(s)
		{
			case LABLE:
			if(c=='>') s=CONTENT;
			break;
			case CONTENT:
			if(c=='<') s=LABLE;
			else{
				if(c=='\n')c=' ';
				content->push_back(c);
			}
			break;
			default:
			break;
		}
	}
	return true;
}
bool ParseUrl(const std::string &file_path, std::string *url)
{
	std::string url_head = "https://www.boost.org/doc/libs/1_78_0/doc/html";
    std::string url_tail = file_path.substr(src_path.size());

    *url = url_head + url_tail;
    return true;
}
bool ParseHtml(const std::vector<std::string> &file_list,std::vector<DocInfo_t>*results)
{
	for(auto &file:file_list)
	{
	//1.读取文件
	std::string result;
	if(!tool::FileTool::ReadFile(file,&result))
	{
		continue;
	}
	DocInfo_t doc;
	//2.解析指定的文件，提取title
	if(!ParseTitle(result,&doc.title))
	continue;
	//3.解析指定的文件，提取content，就是去标签
	if(!ParseContent(result,&doc.content))
	continue;
	//4.解析指定的文件，构建url
	if(!ParseUrl(file,&doc.url))
	continue;
	results->push_back(std::move(doc));
	}
	return true;
}
bool SaveHtml(const std::vector<DocInfo_t>&results,const std::string &output)
{
	#define SEP '\3'
	//按照二级制方式写入
	std::ofstream out(output,std::ios::out|std::ios::binary);
	if(!out.is_open())
	{
		std::cerr<<"open"<<output<<"failed"<<std::endl;
		return false;
	}
	for(auto &item : results){
        std::string out_string;
        out_string = item.title;
        out_string += SEP;
        out_string += item.content;
        out_string += SEP;
        out_string += item.url;
        out_string += '\n';

        out.write(out_string.c_str(), out_string.size());
    }
	out.close();
	return true;
}
int  main()
{
	std::vector<std::string> file_list;
	//第一步，递归式的把每个html文件名带路劲，保存到file_list中
	if(!EnumFile(src_path,&file_list)){

		std::cerr<<"enum file error"<<std::endl;
		return 1;

	}
	//第二步，按照file_list读取每个文件的内容，并进行解析
	std::vector<DocInfo_t> result;
	if(!ParseHtml(file_list,&result))
	{
		std::cerr<<"parse html error"<<std::endl;
		return 2;
	}
	//第三步，把解析完毕的各个文件内容，写入到output，按照\3作为每个文档的分隔符
	if(!SaveHtml(result,output))
	{
		std::cerr<<"save html error"<<std::endl;
		return 3;

	}
}
